import React, {Component} from "react";
import { connect } from 'react-redux';
import _ from 'lodash'

class Posture3D extends Component {
  constructor(props) {
    super(props);

    const $t = this;
    $t.container = null;

    let renderer;
    let camera;
    let scene;
    let light,mesh,fontOptions,planeMesh;

    function initThree() {
      const width = $t.container.clientWidth;
      const height = $t.container.clientHeight;

      renderer = new THREE.WebGLRenderer({
        antialias: true
      });

      renderer.setSize(width, height);
      renderer.setPixelRatio(window.devicePixelRatio);

      $t.container.appendChild(renderer.domElement);
    }

    function initCamera(x, y, z) {
      const width = $t.container.clientWidth;
      const height = $t.container.clientHeight;

      camera = new THREE.PerspectiveCamera(75, width / height, 1, 1e10);
      camera.position.set(x, y, z);
      camera.lookAt(x, y, z);
    }

    function initScene() {
      scene = new THREE.Scene();
      scene.add(camera)
    }

    function initLight() {
      light = new THREE.DirectionalLight(0xffffff,1.0, 0);
      light.position.set(50, 80, 80);
      scene.add(light);
    }
    
    function initFont() {
      const loader = new THREE.FontLoader();

      loader.load("./static/threejs/fonts/gentilis_regular.typeface.json",font=>{
        fontOptions = {
          size:20,
          height: 0.03,
          weight: 'normal',
          font,
          style: 'normal',
          bevelThickness: 1,
          bevelSize: 1,
          curveSegments: 30,
          bevelEnabled: true,
        };

        renderText("X",20,0xff0000,{x:220});
        renderText("Z",20,0xff0000,{y:220});
        renderText("Y",5,0xff0000,{x:-10,z:220});
      })
    }


    function renderText(text,size,color,{x,y,z}) {
      const options = _.cloneDeep(fontOptions);
      options.size = size || 20;

      const textGeo = new THREE.TextGeometry(text, options);
      textGeo.computeBoundingBox();
      textGeo.computeVertexNormals();

      const material = [
        new THREE.MeshPhongMaterial( { color} ), // front
        new THREE.MeshPhongMaterial( { color } ) // side
      ];
      mesh = new THREE.Mesh(textGeo,material );
      mesh.position.x = x || 0;
      mesh.position.y = y || 0;
      mesh.position.z = z || 0;

      scene.add(mesh );
    }
    
    function initObject() {
      // const gridXZ = new THREE.GridHelper($t.container.clientWidth / 1.25, 10, 0xCCFF99, 0xCCFF99);
      // gridXZ.position.set(0,0,0);
      // scene.add(gridXZ);

      const axesHelper = new THREE.AxesHelper(200);
      scene.add( axesHelper );

      // let dir  =new THREE.Vector3(10, 0, 0);
      // dir.normalize();
      //
      // let arrowHelper = new THREE.ArrowHelper(dir, new THREE.Vector3(200,0, 0), 30, 0xffff00,50,20);
      // scene.add(arrowHelper);

      // dir  =new THREE.Vector3(0, 10, 0);
      // dir.normalize();
      // arrowHelper = new THREE.ArrowHelper(dir, new THREE.Vector3(0,200, 0), 30, 0xffff00,50,20);
      // scene.add(arrowHelper);
      //
      // dir  =new THREE.Vector3(0, 0,10);
      // dir.normalize();
      // arrowHelper = new THREE.ArrowHelper(dir, new THREE.Vector3(0,0,200), 30, 0xffff00,25,8);
      // scene.add(arrowHelper);

      const material = new THREE.MeshLambertMaterial({color: 0x9999CC, side: THREE.DoubleSide});
      const loader = new THREE.STLLoader();
      loader.load("./static/threejs/plane.STL", (geometry) => {
        geometry.center();
        geometry.computeVertexNormals();

        planeMesh = new THREE.Mesh(geometry, material);
        planeMesh.position.set(0,0,0 );
        planeMesh.scale.multiplyScalar(3);
        scene.add(planeMesh);
      });
    }
    
    function animate() {
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }

    function threeStart() {
      initThree();
      initCamera(50,50,300);
      initScene();
      initLight();
      initFont();
      initObject();
    }

    let modalEnable = false;
    this.componentDidMount = () => {
      $t.container = $t.refs.container;
      setTimeout(() => {
        threeStart();
        animate();
        modalEnable = true;
      }, 300)
    };


    $t.componentDidUpdate = ()=>{
      const {angleFlush} = $t.props;
      if(angleFlush && modalEnable && planeMesh){
        planeMesh.rotation.y =  parseFloat(angleFlush[9])/180*Math.PI;
        planeMesh.rotation.z =  -1*parseFloat(angleFlush[8])/180*Math.PI;
        planeMesh.rotation.x =  parseFloat(angleFlush[7])/180*Math.PI;
      }
    };

    this.render = () => (
      <div className="modal-a" ref="container"/>
    )
  }
}

export default connect(
  ({angleFlush})=>({angleFlush}),
  ()=>({})
)(Posture3D);
